﻿using GuanYijia.EntityFarmeworkCore;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;

namespace GuanYijia.Repository
{

    public class BaseRepository<T> : IBaseRepository<T> where T : class
    {
        private readonly GuanYiJiaDbContext db;

        public BaseRepository(GuanYiJiaDbContext db)
        {
            this.db = db;
        }
        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        public virtual async Task<int> InsertAsync(T entity)

        {
            await db.Set<T>().AddAsync(entity);
            return await db.SaveChangesAsync();
        }
        /// <summary>
        /// 批量添加数据
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        public virtual async Task<int> InsertRangeAsync(List<T> entity)
        {
            await db.Set<T>().AddRangeAsync(entity);
            return await db.SaveChangesAsync();
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="eneity">实体</param>
        /// <returns></returns>
        public async Task<int> UpdateAsync(T eneity)
        {
            db.Set<T>().Update(eneity);
            return await db.SaveChangesAsync();
        }
        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="eneity">实体</param>
        /// <returns></returns>
        public async Task<int> UpdateRangeAsync(List<T> entity)
        {
            db.Set<T>().UpdateRange(entity);
            return await db.SaveChangesAsync();
        }
        /// <summary>
        /// 单删除
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<int> DeletedAsync(T enity)
        {
            db.Set<T>().Remove(enity);
            return await db.SaveChangesAsync();
        }

        /// <summary>
        /// 单删除根据Id
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<int> DeltedByIdAsync(int Id)
        {
            var aa = await db.Set<T>().FindAsync(Id);
            db.Set<T>().Remove(aa);
            return await db.SaveChangesAsync();
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<int> DelRanageAsync(T entity)
        {

            db.Set<T>().RemoveRange(entity);
            return await db.SaveChangesAsync();
        }
        public async Task<int> DelRanageAsync(Expression<Func<T, bool>> expression)
        {
            var entities = await db.Set<T>().Where(expression).ToListAsync();
            db.Set<T>().RemoveRange(entities);
            return await db.SaveChangesAsync();
        }
        /// <summary>
        /// 查询所有数据
        /// </summary>
        /// <returns></returns>
        public virtual async Task<List<T>> GetAllAsync()
        {

            var list = await db.Set<T>().ToListAsync();
            return list;

        }
        // 重载方法，接受一个 IQueryable<T> 的修改函数  
        public virtual async Task<List<T>> GetAllAsync(Func<IQueryable<T>, IQueryable<T>> queryModifier)
        {
            if (queryModifier == null)
            {
                throw new ArgumentNullException(nameof(queryModifier));
            }

            // 获取 IQueryable<T> 对象  
            var query = db.Set<T>().AsQueryable();

            // 应用修改函数  
            var modifiedQuery = queryModifier(query);

            // 执行查询并返回结果  
            var list = await modifiedQuery.ToListAsync();
            return list;
        }
        //IQueryable查询全部
        public virtual IQueryable<T> GetQueryable(bool tracking = true)
        {
            if (tracking)
            {
                return db.Set<T>().AsQueryable();
            }
            else
            {
                return db.Set<T>().AsNoTracking().AsQueryable();
            }
        }
        public virtual IQueryable<T> GetQueryable1(string tableName, bool tracking = true)
        {
            var dbSet = db.Set<T>();
            if (!tracking)
            {
                dbSet = (DbSet<T>)dbSet.AsNoTracking();
            }

            // 使用反射获取指定表名的 DbSet
            var entityType = typeof(T);
            var dbSetProperty = db.GetType().GetProperties()
                .FirstOrDefault(p => p.PropertyType.IsGenericType &&
                                     p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)
                                     && p.PropertyType.GenericTypeArguments[0] == entityType);

            if (dbSetProperty != null)
            {
                var dbSetInstance = dbSetProperty.GetValue(db);
                return (IQueryable<T>)dbSetInstance;
            }

            throw new ArgumentException($"Table '{tableName}' not found.");
        }
        /// <summary>
        /// 查询所有数据
        /// </summary>
        /// <param name="expression">lambda表达式</param>
        /// <returns></returns>
        public virtual async Task<IList<T>> GetAllAsync(Expression<Func<T, bool>> exception)
        {
            return await db.Set<T>().Where(exception).ToListAsync();
        }
        /// <summary>
        /// 查询所有数据List版
        /// </summary>
        /// <param name="expression">lambda表达式</param>
        /// <returns></returns>
        public virtual async Task<List<T>> GetAllAsyncList(Expression<Func<T, bool>> exception)
        {
            return await db.Set<T>().Where(exception).ToListAsync();
        }
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public virtual async Task<T> GetAsync(int Id)
        {
            return await db.Set<T>().FindAsync(Id);
        }
        /// <summary>
        /// 获取单个对象(通过条件)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual async Task<T> GetAsync(Expression<Func<T, bool>> expression)
        {
            return await db.Set<T>().Where(expression).FirstOrDefaultAsync();
        }
    }
}